package com.xiao.gulimall.search.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.xiao.common.utils.PageUtils;
import com.xiao.gulimall.search.config.GuliESConfig;
import com.xiao.gulimall.search.util.Search;
import com.xiao.gulimall.search.util.Searches;
import com.xiao.gulimall.search.vo.Goods;
import lombok.SneakyThrows;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

@Service
public class EsService {

    @Autowired
    private RestHighLevelClient client;

    public PageUtils mohu(Search search, Integer size, Integer page) {
        Integer size1=size;
        Integer page1=page;
       // 创建SearchRequest
        SearchRequest searchRequest = new SearchRequest("1901a");
        //大多数搜索参数都添加到SearchSourceBuilder. 它为进入搜索请求正文的所有内容提供设置器。
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //查询
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if(search.getTitle()!=null && search.getTitle()!=""){
            queryBuilder.must(QueryBuilders.matchQuery("title",search.getTitle()));
        }
        //分页
        searchSourceBuilder.from(page);
        searchSourceBuilder.size((page-1)*size);
        //高量
        if(search.getTitle()!=null && search.getTitle()!=""){
            HighlightBuilder highlightBuilder = new HighlightBuilder ();
            HighlightBuilder.Field title = new HighlightBuilder.Field("title");
            title.highlighterType("unified");
            highlightBuilder.field(title);
            HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user");
            highlightBuilder.field(highlightUser);
            searchSourceBuilder.highlighter(highlightBuilder);
        }
        //请求
        searchRequest.source(searchSourceBuilder);
        try {
            //响应
            SearchResponse searchResponse = client.search(searchRequest, GuliESConfig.COMMON_OPTIONS);
            SearchHits hits = searchResponse.getHits();
            TotalHits totalHits = hits.getTotalHits();
            long numHits = totalHits.value;
            TotalHits.Relation relation = totalHits.relation;
            float maxScore = hits.getMaxScore();

            ArrayList<Goods> list = new ArrayList<>();

            SearchHit[] searchHits = hits.getHits();
            for (SearchHit hit : searchHits) {
                String index = hit.getIndex();
                String id = hit.getId();
                float score = hit.getScore();
                String sourceAsString = hit.getSourceAsString();
                //JSON转换为对象
                Goods parseObject = JSON.parseObject(sourceAsString, new TypeReference<Goods>() {
                });
                parseObject.setId(id);
                //处理高量
                if(search.getTitle()!=null && search.getTitle()!=""){
                    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                    HighlightField highlight = highlightFields.get("title");
                    if(highlight!=null){
                        Text[] fragments = highlight.fragments();
                        String fragmentString = fragments[0].string();
                        parseObject.setTitle(fragmentString);
                    }
                }
                list.add(parseObject);
            }
            System.out.println(list);//列表
            System.out.println(numHits);//总记录数
            return new PageUtils(list,(int)numHits,size,page);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @SneakyThrows
    public PageUtils testes(Integer page, Integer size, Searches searches) {
        SearchRequest searchRequest = new SearchRequest("1901a");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //查询  生成复合查询构造器
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if(searches.getTitle()!=null && searches.getTitle().length()>0){
            queryBuilder.must(QueryBuilders.matchQuery("title",searches.getTitle()));
        }
        //分页
        searchSourceBuilder.from(page);
        searchSourceBuilder.size(size);

        //高量
        if(searches.getTitle()!=null && searches.getTitle().length()>0){
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            HighlightBuilder.Field field = new HighlightBuilder.Field("title");
            field.highlighterType("unified");
            highlightBuilder.field(field);
            highlightBuilder.preTags("<span style='color:red'>");
            highlightBuilder.postTags("</span>");
            searchSourceBuilder.highlighter(highlightBuilder);

        }
        //请求
        searchRequest.source(searchSourceBuilder);
        //响应
        SearchResponse response = client.search(searchRequest, GuliESConfig.COMMON_OPTIONS);
        SearchHits hits = response.getHits();
        TotalHits totalHits = hits.getTotalHits();
// the total number of hits, must be interpreted in the context of totalHits.relation
        long numHits = totalHits.value;
        TotalHits.Relation relation = totalHits.relation;
        float maxScore = hits.getMaxScore();

        ArrayList<Goods> list = new ArrayList<>();

        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            String index = hit.getIndex();
            String id = hit.getId();
            float score = hit.getScore();
            String sourceAsString = hit.getSourceAsString();
            //转换为对象类型
            Goods goods = JSON.parseObject(sourceAsString, new TypeReference<Goods>() {
            });
            if(searches.getTitle() != null && !searches.getTitle().equals("")){
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField highlight = highlightFields.get("title");
                if(highlight!=null){
                    Text[] fragments = highlight.fragments();
                    String fragmentString = fragments[0].string();
                    goods.setTitle(fragmentString);
                }
            }
            goods.setId(id);
            list.add(goods);
        }
        System.out.println(list);
        System.out.println("记录数"+numHits);
        return new PageUtils(list,(int)numHits,size,page);
    }
}
